import time
import datetime as dt
import re
import traceback



class Dt:
    def __init__(self, string, fmt, raw_str=None):
        self.str = string # 格式为"%Y-%m-%d %H:%M:%S"时间字符串
        self.raw_str = raw_str # 原始的时间字符串
        if self.raw_str is None:
            self.raw_str = self.str
        self.fmt = fmt
        self.dt = dt.datetime.strptime(string, fmt) # datetime类型的时间


class Str2Time:
    def __init__(self, string):
        """
            尽可能识别字符串中的日期时间
        """
        self.str = string # 要识别的字符串
        self.tt = [] # 提取出的时间列表，列表元素为Dt对象
        self.parse_time() # 开始识别
        
    def parse_time(self):
        # 年月日3/4/2024 08:50:00
        not_num = r"(?<!\d)"
        not_num_end = r"(?!\d| *: *)"
        sep = r"(?! *: *)[^\w:]{0,10}" # (?! *: *)不匹配以:为分隔符的数字，这是为了防止04/01/2024 18:45匹配到2024 18:45
        day = r"(?P<day>\d{1,2})"
        month = r"(?P<month>\d{1,2})"
        month_word = r"(?P<month>[a-zA-Z]{3})"
        year = r"(?P<year>\d{4})"
        date_patterns = [
            not_num+day+sep+month_word+sep+year+not_num_end, 
            not_num+year+sep+month+sep+day+not_num_end, 
            not_num+month+sep+day+sep+year+not_num_end, 
        ]
        # 时分(秒)
        hour_pattern = r"([^\w:]{1,5}(?P<hour>\d{1,2}) *?: *?(?P<minute>\d{1,2})( *?: *?(?P<second>\d{1,2}))?)?"
        string = self.str
        match = True
        while match:
            for i,p in enumerate(date_patterns):
                match = re.search(p+hour_pattern, string, flags=re.I)
                
                if match:
                    # print(match.group()) 
                    fmt = "%Y-%m-%d" if i!=0 else "%Y-%b-%d"
                    dt_str = f'{match.group("year")}-{match.group("month")}-{match.group("day")}'
                    if match.group("second"):
                        fmt += ' %H:%M:%S'
                        dt_str += f' {match.group("hour")}:{match.group("minute")}:{match.group("second")}'
                    elif match.group("minute"):
                        fmt += ' %H:%M'
                        dt_str += f' {match.group("hour")}:{match.group("minute")}'
                    try:
                        self.tt.append(Dt(dt_str, fmt, match.group())) 
                    except:
                        # traceback.print_exc()
                        pass
                    string = string.replace(match.group(), '')
                    break


if __name__ == "__main__":
    string = '''这是第一个日期04 /02/@@2024 18:43:02这是第二个日期2024/~-04 -02  19:03 第三个日期02- Apr-2024
    第四个日期31- Aug/2023 20:03第五个日期3/4/2024 08:50:00第六个日期20240306 19:12
    '''
    tt = Str2Time(string)
    for t in tt.tt:
        print(t.raw_str, t.dt)
